using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace eyeArchive.Core
{
	internal class Dependency
	{
		private Table pkTableObject;
		private Column pkColumnObject;
		private string pkQualifier;
		private string pkOwner;
		private string pkName;
		private string pkColumn;

		private Table fkTableObject;
		private Column fkColumnObject;
		private string fkQualifier;
		private string fkOwner;
		private string fkName;
		private string fkColumn;

		private bool recurrent;
		private string depName;

		internal Dependency(Table primary, Table foreign, SqlDataReader row)
		{
			// ===============================================================
			// === Pre-Process                                             ===
			// ===============================================================
			// === Save the parameters =======================================
			pkColumnObject = null;
			fkColumnObject = null;

			if (primary != null)
				this.pkTableObject = primary;
			else
				throw new ArgumentNullException("The primary object cannot be null");

			if (foreign != null)
				this.fkTableObject = foreign;
			else
				throw new ArgumentNullException("The foreign object cannot be null");

			pkQualifier = row["PKTable_Qualifier"].ToString();
			pkOwner = row["PKTable_Owner"].ToString();
			pkName = row["PKTable_Name"].ToString();
			pkColumn = row["PKColumn_Name"].ToString();
			fkQualifier = row["FKTable_Qualifier"].ToString();
			fkOwner = row["FKTable_Owner"].ToString();
			fkName = row["FKTable_Name"].ToString();
			fkColumn = row["FKColumn_Name"].ToString();
			depName = row["FK_NAME"].ToString();

			// ===============================================================
			// === Process                                                 ===
			// ===============================================================
			recurrent = ((pkQualifier == fkQualifier) && (pkOwner == fkOwner) && (pkName == fkName));

			// === Set the column objects ====================================
			foreach (Column item in pkTableObject.Columns)
				if (item.Name == pkColumn)
				{
					pkColumnObject = item;
					break;
				}
			if (pkColumnObject == null)
				throw new InvalidOperationException(string.Format("The column [{0}] has not be found in [{1}].[{2}] while finding primary key column", pkColumn, pkOwner, pkName));

			foreach (Column item in fkTableObject.Columns)
				if (item.Name == fkColumn)
				{
					fkColumnObject = item;
					break;
				}
			if (fkColumnObject == null)
				throw new InvalidOperationException(string.Format("The column [{0}] has not be found in [{1}].[{2}] while finding foreign key column", fkColumn, fkOwner, fkName));
		}

		#region "Properties"
		internal string PrimaryDatabase
		{
			get { return pkQualifier; }
		}

		internal string PrimarySchema
		{
			get { return pkOwner; }
		}

		internal string PrimaryTable
		{
			get { return pkName; }
		}

		internal string PrimaryKey
		{
			get { return pkColumn; }
		}
		internal string ForeignDatabase
		{
			get { return fkQualifier; }
		}

		internal string ForeignSchema
		{
			get { return fkOwner; }
		}

		internal string ForeignTable
		{
			get { return fkName; }
		}

		internal string ForeignKey
		{
			get { return fkColumn; }
		}

		internal bool IsRecurrent
		{
			get { return recurrent; }
		}

		internal Table PrimaryObject
		{
			get { return pkTableObject; }
		}

		internal Table ForeignObject
		{
			get { return fkTableObject; }
		}
		#endregion

		#region "Methods"
		internal string ForeignKeyToString()
		{
			return fkColumnObject.ToString2();
		}

		internal string PrimaryKeyToString()
		{
			return pkColumnObject.ToString2();
		}

		internal string DepName
		{
			get { return depName; }
		}


		#endregion
	}
}
